package cn.edu.nuaa.codemetric.service;

import com.alibaba.fastjson.JSONObject;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.springframework.stereotype.Service;

import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.TimeUnit;

@Service
public class MetricService {

    public String getCodeMetric(String language, String code) throws Exception {

        Random random=new Random();
        random.setSeed(System.currentTimeMillis());
        String r= String.valueOf(random.nextInt());
        String dir="./metric/"+r+"/";
        String filePath;
        if(language.equals("java")) filePath=dir+"code.java";
        else if (language.equals("cpp")) filePath=dir+"code.cpp";
        else if (language.equals("c")) filePath=dir+"code.c";
        else filePath=dir+"code.txt";

        createDir(dir);
        createCodeFile(filePath,code);

        //调用cccc
        String command="cccc --outdir="+dir+" "+filePath;
        System.out.println("执行命令"+command);
        Process process=Runtime.getRuntime().exec(command);
        process.waitFor(20, TimeUnit.SECONDS);

        //加载cccc.xml
        String fileResult=dir+"cccc.xml";
        if(new File(fileResult).exists()){
            Document document= DocumentHelper.parseText(readFile(fileResult));
            Element root=document.getRootElement();
            System.out.println(root.getName());
            Element summary=root.element("project_summary");
            List<Element> metricElements=summary.elements();
            JSONObject jsonObject=new JSONObject();
            for(Element e:metricElements){
                jsonObject.put(e.getName(),e.attribute("value").getValue());
                System.out.println(e.getName()+"....."+e.attribute("value").getValue());
            }
            File lockFile=new File(dir+".lock");
            if(lockFile.exists())lockFile.delete();
            return jsonObject.toJSONString();
        }
        File lockFile=new File(dir+".lock");
        if(lockFile.exists())lockFile.delete();
        return null;
    }

    private void createDir(String name) throws IOException {
        //创建一个随机名字的文件夹
        File tempDir=new File(name);
        if(!tempDir.exists()) tempDir.mkdirs();
        File lockFile=new File(name+".lock");
        if(!lockFile.exists()){
            lockFile.createNewFile();
        }

    }

    private void createCodeFile(String dir, String code) throws IOException {
        //创建代码文件
        File fileCode=new File(dir);
        if(!fileCode.exists()){
            fileCode.createNewFile();
        }else {
            fileCode.delete();
            fileCode.createNewFile();
        }
        FileOutputStream fileOutputStream=new FileOutputStream(fileCode);
        PrintWriter printWriter=new PrintWriter(fileOutputStream);
        printWriter.write(code);
        printWriter.close();
    }


    private String readFile(String path) throws Exception {
        File file=new File(path);
        FileInputStream fis = new FileInputStream(file);
        FileChannel fc = fis.getChannel();
        ByteBuffer bb = ByteBuffer.allocate(new Long(file.length()).intValue());
        //fc向buffer中读入数据
        fc.read(bb);
        bb.flip();
        String str=new String(bb.array(), StandardCharsets.UTF_8);
        fc.close();
        fis.close();
        return str;

    }
}
